package photogcalc.common;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CustomItem;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.ItemCommandListener;

/** A custom slider item.
 *
 * @author aokkonen@gmail.com
 */
public class Slider extends CustomItem implements ItemCommandListener {

    protected final int LEFT  = -1;
    protected final int RIGHT =  1;
    protected final int NONE  =  0;

    protected final int TRAVERSE_IN  = 0;
    protected final int TRAVERSE_OUT = 1;
    protected int isTraverseInOrOut  = TRAVERSE_OUT;

    private final int padding_left   = 5;
    private final int padding_right  = 10;
    private final int padding_top    = 5;
    private final int padding_bottom = 20;
    private final int min_height     = 36;
    private final int min_width      = 96;

    private double min = 1;
    private double max = 100;
    private double step = 1;
    private double val = 1;
    private String valStr = null;

    public Slider(String label) {
        super(label);
    }

    public Slider(String label, double min, double max) {
        super(label);
        this.min = min;
        this.max = max;
    }

    public Slider(String label, double min, double max, double step) {
        super(label);
        this.min = min;
        this.max = max;
        this.step = step;
    }

    /** Returns the minimal height of the content area. */
    protected int getMinContentHeight() {
        return min_height;
    }

    /** Returns the minimal width of the content area. */
    protected int getMinContentWidth() {
        return min_width;
    }

    /** Returns the preferred height of the content
     * area. A tentative value for the opposite
     * dimension -- the width -- is passed to aid
     * in the height calculation. The tentative value
     * should be ignored if it is -1.
     */
    protected int getPrefContentHeight(int width) {
        return getMinContentHeight();
    }

    /** Returns the preferred width of the content
     * area. A tentative value for the opposite
     * dimension -- the height -- is passed to aid
     * in the height calculation. The tentative value
     * should be ignored if it is -1.
     */
    protected int getPrefContentWidth(int height) {
        return 320; //getMinContentWidth();
    }

    protected void paint(Graphics g, int w, int h) {
        int scaledPos = (int)(val * ((double)(w-padding_right) / (double)max));

        g.drawString(""+getValueStr(), 5, h-padding_bottom, Graphics.TOP | Graphics.LEFT);

        // draw slider with gray color if not focused
        // the text is left black
        if (isTraverseInOrOut == TRAVERSE_IN)
            g.setGrayScale(0);
        else
            g.setGrayScale(72);

        g.drawRect(padding_left, padding_top, w-padding_right, 5);
        g.fillRect(padding_left + scaledPos - 2, padding_top - 2, 4, 10);
    }

    /** @see http://developers.sun.com/mobility/midp/ttips/customitemtraversal/index.html */
    protected boolean traverse(int dir, int viewportWidth, int viewportHeight, int visRect_inOut[]) {
      switch (dir) {
        case Canvas.LEFT:
            updatePosition(LEFT);
            isTraverseInOrOut = TRAVERSE_IN;
            repaint();
          break;

        case Canvas.RIGHT:
            updatePosition(RIGHT);
            isTraverseInOrOut = TRAVERSE_IN;
            repaint();
          break;


          case Canvas.DOWN:
          case Canvas.UP:
            if (isTraverseInOrOut == TRAVERSE_OUT)
                isTraverseInOrOut = TRAVERSE_IN;
            else
                isTraverseInOrOut = TRAVERSE_OUT;
      }

      if (isTraverseInOrOut == TRAVERSE_IN)
          return true;
      else
          return false;
    }

    public void commandAction(Command c, Item item) {
    }

    protected void updatePosition(int direction) {
        if (direction == LEFT) {
            val = (val - step < min) ? min : val - step;
        }
        else if (direction == RIGHT) {
            val = (val + step > max) ? max : val + step;
        }
    }

    public double getMax() {
        return max;
    }

    public void setMax(double max) {
        this.max = max;
        invalidate();
    }

    public double getMin() {
        return min;
    }

    public void setMin(double min) {
        this.min = min;
        invalidate();
    }

    public double getValue() {
        return val;
    }

    public void setValue(double val) {
        this.val = val;
        invalidate();
    }

    public double getStep() {
        return step;
    }

    public void setStep(double step) {
        this.step = step;
    }

//    protected void setValueStr(String valStr) {
//        this.valStr = valStr;
//    }

    protected String getValueStr() {
        return Double.toString(val);
    }
    /*protected void keyPressed(int keyCode) {
        System.out.println("keyCode: " + (char)keyCode);
        valStr = Double.toString(val);

        // numbers 0--9
        if (keyCode >= 48 && keyCode <= 57)
            valStr += (char)keyCode;
        // backspace
        else if (keyCode == 4)
            valStr = valStr.substring(1, valStr.length()-1);

        val = Double.parseDouble(valStr);

        invalidate();
    }*/
}
